package com.base.core.head.ao;

import java.io.Serializable;
import java.util.List;

import com.base.core.head.vo.WsMessageListVO;
import com.base.core.head.vo.WsMessageObjectVO;
import com.base.core.head.vo.WsMessagePageVO;
import com.base.core.head.vo.WsMessageVO;
import com.gitee.magic.core.valid.annotation.Format;
import com.gitee.magic.core.valid.annotation.Format.FormatType;
import com.gitee.magic.core.valid.annotation.Length;
import com.gitee.magic.core.valid.annotation.NotNull;
import com.gitee.magic.core.valid.annotation.number.LongValid;
import com.gitee.magic.framework.head.vo.QueryVO;

import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * 
 * @author start
 *
 */
@Getter@Setter@ToString
public class WsMessageAO<T> implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Schema(description="客户端消息Id(下行数据时原样返回方便客户端消息分组)",requiredMode = RequiredMode.REQUIRED)
	@NotNull
	@Format(type = FormatType.MD5)
	private String clientId;

	@Schema(description="请求Id(内部生成)",hidden = true)
	private String requestId;

	@Schema(description="用户Id",hidden = true)
	@LongValid
	private Long userId;

	@Schema(description="目标Id(用户Id、群组Id、剧情卡Id)根据业务(bizType)决定")
	@LongValid
	private Long targetId;
	
	@Schema(description="业务类型",requiredMode = RequiredMode.REQUIRED)
	@NotNull
	@Length
	private String bizType;
	
	@Schema(description="消息类型",requiredMode = RequiredMode.REQUIRED)
	@NotNull
	@Length
	private String msgType;

	@Schema(description="时间戳(客户端上行本地时间)",requiredMode = RequiredMode.REQUIRED)
	@NotNull
	@LongValid
	private Long timestamp;
	
	@Schema(description="数据")
	private T data;
	
	//State
	
	public WsMessageVO ofState(int code) {
		return ofState(code,null);
	}
	
	public WsMessageVO ofState(String message) {
		return ofState(0,message);
	}
	
	public WsMessageVO ofState(int code,String message) {
		WsMessageVO vo=new WsMessageVO(
				code,
				this.getClientId(),
				this.getRequestId(),
				this.getBizType(),
				msgType,
				targetId);
		vo.setMessage(message);
		return vo;
	}
	
	//Default
	
	public WsMessageVO of() {
		return of(this.getMsgType(),this.getTargetId());
	}
	
	public WsMessageVO of(String msgType) {
		return of(msgType,this.getTargetId());
	}
	
	public WsMessageVO of(Long targetId) {
		return of(this.getMsgType(),targetId);
	}
	
	public WsMessageVO of(String msgType,Long targetId) {
		WsMessageVO vo=new WsMessageVO(
				this.getClientId(),
				this.getRequestId(),
				this.getBizType(),
				msgType,
				targetId);
		return vo;
	}
	
	//Object
	
	public <R>WsMessageObjectVO<R> of(R data){
		return of(this.getMsgType(),this.getTargetId(),data);
	}
	
	public <R>WsMessageObjectVO<R> of(String msgType,R data){
		return of(msgType,this.getTargetId(),data);
	}
	
	public <R>WsMessageObjectVO<R> of(Long targetId,R data){
		return of(this.getMsgType(),targetId,data);
	}
	
	public <R>WsMessageObjectVO<R> of(String msgType,Long targetId,R data){
		WsMessageObjectVO<R> vo=new WsMessageObjectVO<>(
				this.getClientId(),
				this.getRequestId(),
				this.getBizType(),
				msgType,
				targetId);
		vo.setData(data);
		return vo;
	}
	
	//List
	
	public <R>WsMessageListVO<R> of(List<R> data){
		return of(this.getMsgType(),this.getTargetId(),data);
	}

	public <R>WsMessageListVO<R> of(String msgType,List<R> data){
		return of(msgType,this.getTargetId(),data);
	}
	
	public <R>WsMessageListVO<R> of(Long targetId,List<R> data){
		return of(this.getMsgType(),targetId,data);
	}
	
	public <R>WsMessageListVO<R> of(String msgType,Long targetId,List<R> data){
		WsMessageListVO<R> vo=new WsMessageListVO<>(
				this.getClientId(),
				this.getRequestId(),
				this.getBizType(),
				msgType,
				targetId);
		vo.setData(data);
		return vo;
	}
	
	//Page
	
	public <R>WsMessagePageVO<R> of(QueryVO<R> data){
		return of(this.getMsgType(),this.getTargetId(),data);
	}

	public <R>WsMessagePageVO<R> of(String msgType,QueryVO<R> data){
		return of(msgType,this.getTargetId(),data);
	}
	
	public <R>WsMessagePageVO<R> of(Long targetId,QueryVO<R> data){
		return of(this.getMsgType(),targetId,data);
	}
	
	public <R>WsMessagePageVO<R> of(String msgType,Long targetId,QueryVO<R> data){
		WsMessagePageVO<R> vo=new WsMessagePageVO<>(
				this.getClientId(),
				this.getRequestId(),
				this.getBizType(),
				msgType,
				targetId);
		if(data!=null) {
			vo.setData(data.getData());
			vo.setTotal(data.getTotal());
		}
		return vo;
	}

}
